// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using System.Linq;

namespace SnapObjects.Data.SqlServer
{
    internal class SqlServerSqlTokenizer : SqlTokenizer
    {
        private readonly IList<string> _sqlVariables;

        public SqlServerSqlTokenizer(string sqlText, ISqlGenerationHelper helper)
            : base(sqlText, helper)
        {
            _sqlVariables = new List<string>();
        }

        protected override bool IsKeyword(string text, out SqlKeywordToken keyword)
        {
            if (SqlServerSqlKeywords.IsKeyword(text))
            {
                keyword = new SqlKeywordToken(SqlServerSqlKeywords.Parse(text));

                return true;
            }

            keyword = null;

            return false;
        }

        protected override bool IsCharacter(string text, out SqlCharacterToken character)
        {
            if (SqlServerSqlCharacters.IsCharacter(text))
            {
                character = new SqlCharacterToken(SqlServerSqlCharacters.Parse(text));

                return true;
            }

            character = null;

            return false;
        }

        protected override bool CheckKeywordIegality(string text)
        {
            var isKeyWord = base.CheckKeywordIegality(text);

            if (!isKeyWord)
            {
                var prevIndex = _index - 1;
                var nextIndex = _index + 1;

                var prev = prevIndex > -1 ? _tokens[prevIndex] : String.Empty;
                var next = nextIndex < _tokens.Count ? _tokens[nextIndex] : String.Empty;

                if (String.IsNullOrWhiteSpace(prev) && next.StartsWith("["))
                {
                    return true;
                }
            }

            return isKeyWord;
        }

        protected override bool IsParameter(string text)
        {
            var isParameter = base.IsParameter(text);

            if (isParameter && !_sqlVariables.Contains(text, StringComparer.OrdinalIgnoreCase))
            {
                var preIndex = _index - 1;
                var preText = String.Empty;

                while (preIndex >= 0)
                {
                    if (!String.IsNullOrWhiteSpace(_tokens[preIndex]))
                    {
                        preText = _tokens[preIndex];

                        break;
                    }

                    preIndex--;
                }

                if (!String.IsNullOrWhiteSpace(preText) &&
                    preText.Equals(SqlKeywords.DECLARE.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    _sqlVariables.Add(text);

                    return false;
                }

                return true;
            }

            return false;
        }
    }
}
